TensorFlowで Hello Worldを動かしてみた&その解説
平田です。TensorFlowという機械学習ライブラリが流行っているようなので、とりあえず触ってみました。
ということで、まずはHello worldと、その解説を行っていきたいと思います。
セットアップ & Hello world
まずは、Tensorflowをローカル上にインストールしていきます。今回はOSX上に環境を作っていきます。
はじめにvirtualenvを利用して、tensorflow用の環境を作成します。 tensorflowは今のところpython 2.7上でのみ動くようなので、これに揃えて環境を作成していきます。
$ # python バージョン確認 $ python —version Python 2.7.10 $ # virtualenvのインストール $ easy_install pip $ pip install virtualenv $ # virtualenv環境の作成 $ mkdir ~/tensorflow $ virtualenv -—system-site-packages ~/tensorflow $ # 作成したvirtualenv環境にはいる $ cd ~/tensorflow $ source bin/activate $ # TensorFlowのインストール (tensorflow)$ pip install —upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.5.0-py2-none-any.whl
なかなかお手軽ですね。TensorFlowのインストールだけなら一行で済んでしまいます。 最後に次のスクリプトを実行してみて、きちんとTensorFlowがインストールできているか試してみましょう。
# hello-tf.py import tensorflow as tf import multiprocessing as mp core_num = mp.cpu_count() config = tf.ConfigProto( inter_op_parallelism_threads=core_num, intra_op_parallelism_threads=core_num ) sess = tf.Session(config=config) hello = tf.constant('hello, tensorflow!') print sess.run(hello) a = tf.constant(10) b = tf.constant(32) print sess.run(a+b)
tensorflow 0.5.0 では、今回の環境(macbook air 2015 3.1 GHz Intel Core i7)からコア数を取得できないため、Sessionインスタンス作成時にコア数を指定しないと警告がでます。これを回避するために
multiprocessing
モジュールからcore_num
を取得し、設定値として指定しています。
下記のように結果が返ってくれば、ひとまずインストールは無事に終わっています。
(tensorflow)$ python hello-tf.py I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 4 I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 4 hello, tensorflow! 42
hello world の解説
とりあえずHello Worldは無事に動かせましたが、これだけだと全くTensorFlowのことがわかりません。なので、先ほど動かしたコードを足がかりに、TensorFlowがどのように計算処理を行っているのかを解説していきたいと思います。
TensorFlowにおける計算処理
コードの中身を見て行く前に、TensorFlowにおける計算処理の考え方について説明していきます。
TensorFlowでは、計算処理はグラフで表されます。このグラフというのは、一般的に言われる折れ線グラフのようなものではなく、ノード(Node)とエッジ(Edge)で表現されるデータ構造の一種です。
TensorFlowにおいては、ノードはops(operations)とよばれる一つの計算処理と対応しています。
opsは、Tensorと呼ばれる行列形式のデータを受けとり、計算処理を施したのち、その結果を次のopsに渡していきます。このように、データをグラフ構造に沿って次々にopsに受け渡していき、計算処理を繰り返すことで、最終的に求めたい計算結果を得ることができます。
計算処理グラフを構築したあとは、各opsごとにCPUコアやGPUコアなどの計算資源を割り当て、計算処理を行います。TensorFlowでは、この計算資源の割り当てはSessionとよばれるコンポーネントが担当しています。
TensorFlowの利用例として挙げられているNN系の機械学習は、計算処理としてみると複雑な行列計算の組み合わせでできています。より効率良く学習処理を行うために、各行列処理をopsという単位で区切り、それぞれに計算資源を割り当てる形にしています。
また、このように計算資源の割り当てをSessionに任せることで、実行環境が異なる場合でもSessionがその差異を吸収し、環境に合わせて効率良く分散処理をおこなってくれます。
ここまでの流れをまとめると、TensorFlowの計算処理プログラムは、opsを組み合わせてグラフ構造で計算処理を構築するフローと、Sessionにグラフを渡して実際に計算処理をおこなうフローの2段階があることがわかります。
Hello worldはどのように実行されているか
では、以上を踏まえた上でもう一度Hello worldスクリプトを眺めてみましょう。
config = tf.ConfigProto( inter_op_parallelism_threads=core_num, intra_op_parallelism_threads=core_num ) sess = tf.Session(config=config)
ここでは、先ほどの説明にもあったSessionが作られていることがわかります。今回は環境の問題でコア数を指定してSessionを作成していますが、通常であれば何も指定しない場合でも環境から自動的に計算資源の情報を取得し、これをもとに割り当てを行なっていきます。
# (1) hello = tf.constant('hello, tensorflow!') print sess.run(hello) # (2) a = tf.constant(10) b = tf.constant(32) c = a + b print sess.run(c)
次のコードを見てみましょう(説明しやすいように、少しコードを変更しています)。ここでは、Tensorの作成、グラフの構築、Sessionへの投入・実行を2度行なっています。
tf.constant()
で作られている各変数は、Tensor型のオブジェクトです。一般的にはTensor型は行列データを格納しますが、今回はhello worldなので、単純に文字列や数値をそのまま格納しています。0次元の行列データとして扱われていると考えてください。
(1)では、文字列のTensorをそのままSessionに渡して、計算結果としてその値をそのまま出力させています。Session.run()
の部分で計算を実際におこなっており、計算結果としてhello
内部の値をそのまま返しています。
(2)では、c = a + b
の部分で、実はその場では計算処理を行っていません。cはTensor型で返却されており、a,bを加算した結果を表現する変数ですが、具体的な計算結果は保持していません。c
はあくまで計算の過程をもつのみであり、結果はSessionに投入した際にはじめて確定します。
このように、TensorFlowでは通常の計算プログラムを書く要領で計算過程を保持する変数をつくり、最終的にSessionを通して計算を行い、その結果を返すということがわかります。
おわりに
まずは簡単なHello worldを題材に、TensorFlowにおける計算処理の考え方を紹介いたしました。
まだまだTensorFlowのことはわからない点が多いですが、しばらくはチュートリアルをゆっくり眺めながら、今回の要領で調べていきたいと考えています。
お付き合いいただければ幸いです。